using System;
using System.Drawing;
using System.Collections.Generic;
using System.Text;

using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using TTDotNet.Engine.ThreeDEngine;

namespace TTDotNet.Engine.GUI
{
    public class RadioButton : Control
    {
        private RadioGroup parentGroup;
        private GameTexture _bgChecked;
        private GameTexture _currentBg;

        private int _groupID;
        private bool _deselectable;

        public event ControlDelegate OnDeselect;
        
        public RadioButton(int groupID, RectangleF screenRect, string text, float fontSize, Color fontColor, 
                            string fontName, bool isChecked, bool deselectable, GameTexture bgUnchecked, GameTexture bgChecked)
        {
            if (isChecked) { Data = ControlStateChange.Selected; }
            else { Data = ControlStateChange.Deselected; }

            _deselectable = deselectable;

            _groupID = groupID;

            _size = screenRect;
            _size.Width = bgUnchecked.Texture.GetLevelDescription(0).Width;
            _size.Height = bgUnchecked.Texture.GetLevelDescription(0).Height;
            _text = text;
            _fontSize = fontSize;
            _fontName = fontName;
            
            textureUp = bgUnchecked;
            _bgChecked = bgChecked;
            _currentBg = bgUnchecked;

            _position = new PointF(screenRect.X, screenRect.Y);

            _fontColor = fontColor;
            _fontColorDeselected = fontColor;
            _fontColorSelected = fontColor;

            System.Drawing.Font systemFont = new System.Drawing.Font(fontName, fontSize);

            //if(!text.Equals(String.Empty))
            //font3D = Mesh.TextFromFont(Game.device, systemFont, _text, 0, 0);

            //_font = new Microsoft.DirectX.Direct3D.Font(Game.device, systemFont);
            if(!_text.Equals(String.Empty))
            Game.arial14.PreloadText(_text);
            
            _textRect = new RectangleF(_position.X, _position.Y, 100, _size.Height);
            
            SetSize(screenRect.Width, screenRect.Height);

        }

        protected override void OnMouseRelease(Point cursor)
        {
            if (Contains(cursor))
            {
                if (_deselectable)
                {
                    if ((ControlStateChange)Data == ControlStateChange.Selected) 
                    { 
                        Data = ControlStateChange.Deselected; 
                    }
                    else if ((ControlStateChange)Data == ControlStateChange.Deselected || (ControlStateChange)Data == ControlStateChange.DeselectedByOther) 
                    { 
                        Data = ControlStateChange.Selected;
                        parentGroup.DeselectOthers(this);
                    }
                }
                else
                {
                    Data = ControlStateChange.Selected;
                }

                if ((ControlStateChange)Data == ControlStateChange.Selected)
                {
                    _currentBg = _bgChecked;
                    _fontColor = _fontColorSelected;
                }
                else
                {
                    _currentBg = textureUp;
                    _fontColor = _fontColorDeselected;
                }
            }
            else
            {
                _mouseDown = false;
            }    
        }

        public void Select()
        {
            Data = ControlStateChange.Selected;
            _currentBg = _bgChecked;
            _fontColor = _fontColorSelected;

            OnSelected();
        }

        public void Deselect()
        {
            Data = ControlStateChange.DeselectedByOther;

            _currentBg = textureUp;
            _fontColor = _fontColorDeselected;

            OnDeselected();
        }

        public void SetParentGroup(RadioGroup group) 
        {
            parentGroup = group;
        } 

        public override void Render(PointF location)
        {
            Game.guiSprite.Transform = spriteTransform;
            Game.guiSprite.Draw(_currentBg.Texture, Rectangle.Empty, Vector3.Empty, Vector3.Add(_renderPosition, new Vector3(location.X / WidthScale, location.Y / HeightScale, 0)), Color.White);

            //Game.arial14.PreloadText(_text);
            
            if (!_text.Equals(string.Empty))
            {
                Game.guiSprite.Transform = Matrix.Identity;
                Game.arial14.DrawText(Game.guiSprite, _text, new Rectangle((int)(_textRect.X + location.X), (int)(_textRect.Y + location.Y), (int)_textRect.Width, (int)_textRect.Height), textFormat, _fontColor);
                //Game.arial14.DrawText(Game.guiSprite, _text, Rectangle.Empty, textFormat, _fontColor);

            //if (font3D != null)
            //{
            //    Matrix savedWorld = Game.device.Transform.World;
            //    //Matrix savedView = Game.device.Transform.View;
            //    //Matrix savedProjection = Game.device.Transform.Projection;

            //    Game.device.Transform.World = Matrix.Identity;
            //    //Game.device.Transform.View = Game.myCamera.View;
            //    //Game.device.Transform.Projection = Game.myCamera.Projection;

            //    font3D.DrawSubset(0);

            //    Game.device.Transform.World = savedWorld;
            //    //Game.device.Transform.View = savedView;
            //    //Game.device.Transform.Projection = savedProjection;

            //}

                Game.guiSprite.Transform = spriteTransform;
            }
        }

        public int GroupID
        {
            get { return _groupID; }
        }

        public override object Data
        {
            get
            {
                return (ControlStateChange)base.Data;
            }
            set
            {
                base.Data = value;
            }
        }

        public bool Deselectable
        {
            get { return _deselectable; }
        }

    }

    public class RadioGroup : Control
    {
        private Dictionary<int, RadioButton> buttons;
        private bool drawGroup = true;

        public RadioGroup()
        {
            buttons = new Dictionary<int, RadioButton>();
        }

        public void Add(int num, RadioButton button)
        {
            button.SetParentGroup(this);
            buttons[num] = button;
        }

        public void Remove(int num)
        {
            buttons.Remove(num);
        }

        public void Select(int num)
        {
            buttons[num].Select();
            if (buttons[num].Deselectable)
            {
                DeselectOthers(buttons[num]);
            }
        }

        public void Deselect(int num)
        {
            buttons[num].Deselect();
        }

        public void Clear()
        {
            buttons.Clear();
        }

        public void SetDraw(bool value)
        {
            drawGroup = value;
        }

        public void DeselectOthers(RadioButton button)
        {
            foreach (RadioButton b in buttons.Values)
            {
                if (!(b == button)) b.Deselect();
            }
        }

        public override void Render(PointF location)
        {
            if (drawGroup)
            {
                foreach (RadioButton b in buttons.Values)
                {
                    b.Render(location);
                }
            }
        }

        protected override void OnMouseDown(Point cursor, bool[] buttons)
        {
            foreach (RadioButton b in this.buttons.Values)
            {
                b.MouseHandler(cursor, buttons, 0);
            }
        }

        protected override void OnMouseRelease(Point cursor)
        {
            foreach (RadioButton b in buttons.Values)
            {
                b.MouseHandler(cursor, new bool[3], 0);
            }
        }

        public override bool Contains(Point cursor)
        {
            foreach (RadioButton b in buttons.Values)
            {
                if (b.Contains(cursor)) { return true; }
            }
            return false;
        }

        public override void Dispose()
        {
            foreach (RadioButton b in buttons.Values)
            {
                b.Dispose();
            }
        }

    }

}
